package com.example.boot1.annoself;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Date;


//说明当前对象是一个切面
@Aspect
//允许在spring IOC 对当前对象实例化并管理
@Component
@Slf4j
public class  MethodExporterAspect {
    //说明切面作用范围，任何增加@MethodExporter的目标方法都将在执行方法前先执行该切面方法
    //@Around环绕通知，是最强大的通知类型，可以控制方法入参、执行、返回结果等各方面细节
    @Around("@annotation(com.example.boot1.annoself.MethodExporter)")
    public Object methodExporter(ProceedingJoinPoint joinPoint) throws  Throwable{
        long st = new Date().getTime();
        //执行目标方法，获取目标方法返回值
        Object proceed = joinPoint.proceed();
        long et = new Date().getTime();

        ObjectMapper mapper = new ObjectMapper();
        //将入参json序列化
        String jsonParam = mapper.writeValueAsString(joinPoint.getArgs());
        //将返回结果序列化
        String jsonResult = null;
        if (proceed != null){
            jsonResult = mapper.writeValueAsString(proceed);
        }else {
            jsonResult = "null";
        }
        System.out.println("程序是否进行到这里！");
        //模拟上报过程
        log.info("正在上报服务器调用过程\n target:{}.{}() \n execution:{}ms,\n parameter:{} \n result:{}"
            ,joinPoint.getTarget().getClass().getSimpleName()
            ,joinPoint.getSignature().getName()
            ,(et-st)
            ,jsonParam
            ,jsonResult
        );
        return  proceed;
    }
}
